//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <bsp.h>
#include <init.h>
#include "pic.h"

EXTERN_C DECL_CODEINIT void CDECL InitPIC()
{
    BspMaskAllIrqs(FALSE);
}

EXTERN_C irqs_t CDECL BspGetIrqs()
{
    return (irqs_t)Inw(_INTSR1)
        | ((irqs_t)Inw(_INTSR2) << 16)
        | ((irqs_t)Inb(_INTSR3) << 32);
}

INLINE void EndOfInterrupt(irq_t irq)
{
    switch (irq) {
        case 8: Outl(_TC1EOI, 0); break;
        case 9: Outl(_TC2EOI, 0); break;
    // BUG: Not implement
    }
}

STATIC irqs_t s_irqMask = 0;

EXTERN_C void CDECL BspMaskIrqs(irqs_t irqs, bool_t bEnable)
{
    if (bEnable)
        s_irqMask |= irqs;
    else
        s_irqMask &= ~irqs;

    if (irqs & 0x000000ffffll) Outw(_INTMR1, (uint16_t)s_irqMask);
    if (irqs & 0x00ffff0000ll) Outw(_INTMR2, (uint16_t)(s_irqMask >> 16));
    if (irqs & 0xff00000000ll) Outb(_INTMR3, (uint16_t)(s_irqMask >> 32));
}

EXTERN_C void CDECL BspMaskAllIrqs(bool_t bEnable)
{
    s_irqMask = bEnable? 0xffffffffffll : 0x0000000000ll;

    Outw(_INTMR1, (uint16_t)s_irqMask);
    Outw(_INTMR2, (uint16_t)(s_irqMask >> 16));
    Outb(_INTMR3, (uint16_t)(s_irqMask >> 32));
}

EXTERN_C void CDECL BspAcknowledgeIrq(irq_t irq)
{
    EndOfInterrupt(irq);
}
